home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------- */
- /* SPRITE CUTTER UTILITY v2.0 */
- /* by gaggi@cs.unibo.it */
- /* ---------------------------------------------------- */
- /* CUTLST.C */
- /* sprite cut management module */
- /* ---------------------------------------------------- */
-
- #include <alloc.h>
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
-
- #include "mouse.h"
- #include "graph13h.h"
-
- /* ---------------------------------------------------- */
-
- #include "interfac.h"
- #include "cutlst.h"
- #include "picview.h"
-
- extern void error(unsigned, char *);
- extern void xor_rect(unsigned, unsigned, unsigned, unsigned, unsigned );
- extern void prepare_buffer(struct CUT *, unsigned char far *);
-
- /* ---------------------------------------------------- */
-
- #define MEM_ERR 1
- #define FILE_ERR 2
- #define LOAD_ERR 3
- #define SOURCE_ERR 4
-
- #define CUT_COLOR 0x04
- #define CUT_SIZE sizeof(struct CUT) - sizeof(struct CUT *)
-
- /* ------------- Public Datas ------------------------- */
-
- struct CUT *cut_list; /* Dynamic list containing all the cuts */
-
- picture source_pic; /* Source picture datas: palette and bitmap */
-
- char source_name[MAXSTRINGLEN]; /* File name of the source picture */
-
- unsigned char cut_x_size= 0x08, cut_y_size= 0x08; /* Sizes of the sprite */
-
- /* ------------- Static datas ------------------------- */
-
- static unsigned list_modified= 0;
-
- static char lst_msg[]= "List modified.\rSave(y/n)?";
- static char IO_prompt[]= "LST name ...";
- static char SPR_prompt[]= "SPR file name ...";
-
- /* ------------- static functions -------------------- */
-
- static int load_cuts(int handle)
- /* Loads the list of cuts from file */
- {
- struct CUT *crsr, **last= &cut_list;
- register unsigned ret_val= 0;
-
- while ( !eof(handle) )
- {
- if ( !(*last= crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
- {
- error(MEM_ERR, NULL);
- ret_val= -1;
- break;
- };
-
- if ( read(handle, crsr, CUT_SIZE) != CUT_SIZE )
- {
- ret_val= -1;
- error(LOAD_ERR, NULL);
- break;
- };
-
- last= &(crsr->next);
- }
-
- if (*last) *last= NULL;
-
- close(handle);
- list_modified= 0;
- Draw_cuts();
- return ret_val;
- }
-
- static int write_cuts(FILE *dest)
- /* Writes the list of cuts to a file */
- {
- struct CUT *crsr= cut_list;
-
- while (crsr)
- {
- fwrite(crsr, CUT_SIZE, 1, dest);
- crsr= crsr->next;
- };
-
- list_modified= 0;
- return fclose(dest);
- }
-
-
- static void cut_number(unsigned x, unsigned y, unsigned number)
- /* Puts the ordinal number of cut on the screen at coordinates x, y */
- {
- char temp[3];
-
- Curcol= 0;
- Draw_box(x + 1, y + 1, 15, 7);
-
- Curcol= 15;
- sprintf(temp, "%d", number);
- OutText(x, y, temp);
- }
-
- static void renumber_cut(struct CUT *start, unsigned counter)
- /* Renumbers all the cuts starting from the cut pointed by *start */
- /* and the number counter. */
- {
- unsigned char far *buffer;
- register unsigned temp1= start->width;
- register unsigned temp2= start->height;
-
- if (temp1 < 16 || temp2 < 16) /* if the cut sizes are too small */
- { /* the result of restoring image data */
- Show_picture(&source_pic, NO_SET);/* to cancel cut number is unreadable */
- Draw_cuts(); /* so I redraw picture and all */
- return; /* the cuts */
- };
-
- if (!(buffer= (char far *)farmalloc(temp1*temp2 + 2*sizeof(unsigned))))
- /* If there's not enough memory just draw a black bar to cancel cut */
- /* number ... */
- {
- Curcol= 0;
- Draw_box(start->x + 1, start->y + 1, 15, 7);
- }
- else { /* ... otherwise restore the original picture pixels */
-
- ((unsigned far *)buffer)[0]= temp1; /* Type cast on a Lvalue... ARGH! */
- ((unsigned far *)buffer)[1]= temp2; /* Davoli, please forgive me! */
-
- prepare_buffer(start, buffer);
- put_area(start->x, start->y, buffer);/* Restores original image datas */
- farfree(buffer);
- };
-
- start= start->next;
-
- while (start) /* Now change the number of all remaining cuts */
- {
- cut_number(start->x, start->y, counter++);
- start= start->next;
- };
-
- }
-
- /* ------------- public functions ------------------- */
-
- int load_source(char *file_name)
- {
- char *temp;
-
- if (cut_list) save_LST(1);
-
- temp= (char *)malloc(MAXSTRINGLEN);
-
- if (file_name) strcpy(temp, file_name);
- else if (Input_box("PCX file name ...", temp, MAXSTRINGLEN - 1, 30, 80) <= 0)
- {
- free(temp);
- return -1;
- };
-
- switch ( PCX_load(temp, &source_pic) )
- {
- case 1:
- error(FILE_ERR, temp);
- free(temp);
- return -1;
-
- case EOF:
- case 2:
- error(LOAD_ERR, NULL);
- *source_name= 0;
- destroy_LST();
- clear_video(0);
- free(temp);
- return -1;
- };
-
- destroy_LST();
- strcpy(source_name, temp);
-
- mouse_cursor(OFF);
- Show_picture(&source_pic, SET);
- mouse_cursor(ON);
-
- free(temp);
- return 0;
- }
-
-
- int cut_sprite(unsigned click_x, unsigned click_y)
- /* Adds a cut to the current list of cuts if the cut is not present yet */
- /* otherwise it cancels the cut renumbering all the list */
- {
- struct CUT *crsr= cut_list,
- *last= NULL;
- register unsigned counter= 0;
-
-
- asm sti
- mouse_cursor(OFF);
-
- if (!*source_name) return SOURCE_ERR; /* There's not source picture */
-
- xor_rect(click_x, click_y, cut_x_size, cut_y_size, CUT_COLOR);
- /* Xors the cut on the screen */
- /* So if it is present yet it will be cancelled */
- /* else it will be drawn */
-
- while (crsr)
- {
- if (crsr->x == click_x && crsr->y == click_y && crsr->width == cut_x_size
- && crsr->height == cut_y_size) /* if the cut is present ... */
- {
- if (last) last->next= crsr->next; /* ... unlink it from the list */
- else cut_list= crsr->next;
-
- renumber_cut(crsr, counter); /* and renumber all the remaining */
- free(crsr);
- break;
- };
-
- last= crsr;
- crsr= crsr->next;
- counter++;
- }
-
- if (!crsr) /* if the cut is not present ... */
- { /* ... add it on the list queue */
- if ( !(crsr= (struct CUT *)malloc(sizeof(struct CUT))) )
- {
- mouse_cursor(ON);
- while (Mouse.Button);
- return MEM_ERR;
- };
-
- if (last) last->next= crsr;
- else cut_list= crsr;
-
- crsr->next= NULL;
- crsr->x= click_x;
- crsr->y= click_y;
- crsr->width= cut_x_size;
- crsr->height= cut_y_size;
- cut_number(click_x, click_y, counter);
- };
-
- list_modified= 1;
- mouse_cursor(ON);
- while (Mouse.Button);
- return 0;
- }
-
-
- int save_LST(unsigned ask)
- {
- char *temp;
- FILE *dest;
-
- if ( ask && ( !list_modified || Message_box(lst_msg, 60, 80, 1) <= 0 ) )
- return 0;
-
- if (!cut_list) return 0;
-
- temp= (char *)malloc(MAXSTRINGLEN);
-
- if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
- {
- free(temp);
- return 0;
- };
-
- dest= fopen(temp, "wb");
- free(temp);
-
- fwrite(source_name, sizeof(source_name), 1, dest);
-
- return write_cuts(dest);
- }
-
-
- int load_LST()
- {
- char *temp= (char *)malloc(MAXSTRINGLEN);
- register int handle;
-
- save_LST(1);
-
- if (Input_box(IO_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
- {
- free(temp);
- return 0;
- };
-
- if ( (handle= open(temp, O_RDWR | O_BINARY)) == -1 )
- {
- error(FILE_ERR, temp);
- free(temp);
- return -1;
- };
-
- read(handle, temp, MAXSTRINGLEN);
-
- if ( load_source(temp) ) {
- free(temp);
- return -1;
- };
-
- free(temp);
- destroy_LST();
-
- return load_cuts(handle);
- }
-
-
- int save_SPR()
- /* Writes all the sprites' bitmaps to a file */
- {
- FILE *spr_file;
- char *temp;
- unsigned char far *base;
- struct CUT *crsr;
- register unsigned row, col;
-
- if (!cut_list) return -1;
-
- temp= (char *)malloc(MAXSTRINGLEN);
-
- if (Input_box(SPR_prompt, temp, MAXSTRINGLEN - 1, 10, 80) <= 0)
- {
- free(temp);
- return 0;
- };
-
- spr_file= fopen(temp, "wb");
- free(temp);
-
- crsr= cut_list;
- while (crsr)
- {
-
- fwrite(&crsr->height, sizeof(unsigned char), 2, spr_file);
- base= &(source_pic.buffer[crsr->x + crsr->y * 320]);
-
- for (row= 0; row < crsr->height; row++)
- {
- for (col= 0; col < crsr->width; col++)
- putc(base[col],spr_file);
-
- base += 320;
- };
-
- crsr= crsr->next;
- };
-
- return fclose(spr_file);
- }
-
-
- void destroy_LST()
- {
- struct CUT *crsr= cut_list, *next;
-
- while (crsr)
- {
- next= crsr->next;
- free(crsr);
- crsr= next;
- };
-
- cut_list= NULL;
- }
-
- void Draw_cuts()
- {
- struct CUT *crsr= cut_list;
- register unsigned counter= 0;
-
- mouse_cursor(OFF);
-
- while (crsr)
- {
- xor_rect(crsr->x, crsr->y, crsr->width, crsr->height, CUT_COLOR);
- cut_number(crsr->x, crsr->y, counter++);
- crsr= crsr->next;
- };
-
- mouse_cursor(ON);
- }
-